package cn.scw.project.system.service.impl;

import cn.scw.common.constant.GComConsts;
import cn.scw.common.constant.SysConsts;
import cn.scw.common.separate.ServiceNumberService;
import cn.scw.common.separate.model.MessageTemplateModel;
import cn.scw.common.utils.DateUtils;
import cn.scw.common.utils.StringUtils;
import cn.scw.common.utils.http.HttpPrintUtils;
import cn.scw.common.utils.pay.WXConfigUtil;
import cn.scw.project.facility.domain.FacPrintOrder;
import cn.scw.project.facility.domain.netework.bean.WxSharingOrderResp;
import cn.scw.project.facility.service.IFacPrintOrderService;
import cn.scw.project.facility.service.IWxPayService;
import cn.scw.project.goods.domain.GCommodityOrder;
import cn.scw.project.goods.service.IGCommodityOrderService;
import cn.scw.project.goods.service.IGCouponUserService;
import cn.scw.project.separate.domain.SaUser;
import cn.scw.project.separate.domain.SeparateVo;
import cn.scw.project.separate.service.SaRecordService;
import cn.scw.project.separate.service.SaUserService;
import cn.scw.project.system.domain.SysUser;
import cn.scw.project.system.domain.SysUserExpend;
import cn.scw.project.system.service.ISysPayService;
import cn.scw.project.system.service.ISysUserBrokerageService;
import cn.scw.project.system.service.ISysUserExpendService;
import cn.scw.project.system.service.ISysUserService;
import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: lj
 * @create: 2020-06-05
 **/
@Service
public class SysPayServiceImpl implements ISysPayService {

    @Autowired
    private IFacPrintOrderService iFacPrintOrderService;
    @Autowired
    private IGCommodityOrderService igCommodityOrderService;
    @Autowired
    private ISysUserExpendService iSysUserExpendService;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private IGCouponUserService igCouponUserService;
    @Autowired
    private ISysUserBrokerageService iSysUserBrokerageService;

    @Resource
    private SaRecordService saRecordService;

    @Resource
    private SaUserService saUserService;

    @Resource
    private ServiceNumberService serviceNumberService;

    @Autowired
    private IWxPayService iWxPayService;

    /**
     * 支付回调
     *
     * @param params
     * @return
     */
    @Override
    public synchronized String payBack(Map<String, String> params) {
        if (params == null || params.isEmpty()) return "FAIL";
        String outTransNo = params.get("outTransNo");
        if (!params.get("retCode").equals("0000")) return "FAIL";
        FacPrintOrder facPrintOrder = iFacPrintOrderService.selectFacPrintOrderByNumber(outTransNo);
        if (!facPrintOrder.isPay() && Integer.valueOf(params.get("payStatus")).compareTo(2) == 0) {
            facPrintOrder.setTransactionId(params.get("transactionId"));
            facPrintOrder.setTransNo(params.get("transNo"));
            facPrintOrder.setPay(true);
            facPrintOrder.setPayDate(new Date());
            if (facPrintOrder.getCouponId() != null) igCouponUserService.use(igCouponUserService.selectGCouponUserVoById(facPrintOrder.getCouponId()));
            // 调用打印接口
            System.out.println("执行打印");
            boolean isPrint = HttpPrintUtils.print(facPrintOrder);
            facPrintOrder.setPrint(isPrint);
            iFacPrintOrderService.updateFacPrintOrder(facPrintOrder);
            // 计算佣金
            iSysUserBrokerageService.addSysUserBrokerageMoney(facPrintOrder.getFacilityCode(), facPrintOrder.getPayMoney());

            //更改分账记录状态
            saRecordService.updateOrderState(1, facPrintOrder.getNumber());

            //发送分账通知
            List<SeparateVo> voList = saRecordService.queryUserRecord(facPrintOrder.getId());
            if (voList != null && voList.size() > 0) {
                voList.forEach(user -> {
                    //组装模板消息内容
                    if (StringUtils.isNotBlank(user.getOpenId())) {
                        MessageTemplateModel templateModel = new MessageTemplateModel();
                        templateModel.setFirst(MessageTemplateModel.Model.init("您有一笔分账即将到账，请注意查收"));
                        templateModel.setKeyword1(MessageTemplateModel.Model.init(String.valueOf(user.getGetMoney())));
                        templateModel.setKeyword2(MessageTemplateModel.Model.init("微信支付"));
                        templateModel.setKeyword3(MessageTemplateModel.Model.init(facPrintOrder.getNumber()));
                        templateModel.setKeyword4(MessageTemplateModel.Model.init(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss")));
                        templateModel.setRemark(MessageTemplateModel.Model.init("感谢你的使用。"));
                        serviceNumberService.sendTemplate(user.getOpenId(), templateModel);
                    }
                });
            }
        } else if (!facPrintOrder.isPrint()) {
            boolean isPrint = HttpPrintUtils.print(facPrintOrder);
            facPrintOrder.setPrint(isPrint);
            iFacPrintOrderService.updateFacPrintOrder(facPrintOrder);
        }
        return "SUCCESS";
    }

    @Override
    public WxSharingOrderResp profitsharing(Long orderId) {
        FacPrintOrder facPrintOrder = iFacPrintOrderService.selectFacPrintOrderById(orderId);
        try {
             return shareOrder(facPrintOrder);

        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public synchronized String payBack(String resXml, int type) {
        System.out.println("执行回调");
        WXConfigUtil config = null;
        try {
            config = new WXConfigUtil();
        } catch (Exception e) {
            e.printStackTrace();
        }
        WXPay wxpay = new WXPay(config);
        String xmlBack = "";
        Map<String, String> notifyMap = null;
        try {
            notifyMap = WXPayUtil.xmlToMap(resXml);         // 调用官方SDK转换成map类型数据
            for (String s : notifyMap.keySet()) {
                System.out.println(s + ":" + notifyMap.get(s));
            }
//            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//验证签名是否有效，有效则进一步处理
            String return_code = notifyMap.get("return_code");//状态
            String out_trade_no = notifyMap.get("out_trade_no");//商户订单号
            String transaction_id = notifyMap.get("transaction_id");//微信订单号
            if (return_code.equals("SUCCESS")) {
                if (out_trade_no != null) {
                    // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户的订单状态从退款改成支付成功
                    // 注意特殊情况：微信服务端同样的通知可能会多次发送给商户系统，所以数据持久化之前需要检查是否已经处理过了，处理了直接返回成功标志
                    //业务数据持久化
                    if (SysConsts.PAY_BACK_COMMODITY == type) {
                        GCommodityOrder gCommodityOrder = igCommodityOrderService.selectGCommodityOrderByNumber(out_trade_no);
                        if (!gCommodityOrder.getIsPay()) {
                            gCommodityOrder.setIsPay(true);
                            gCommodityOrder.setStatusCode(GComConsts.ORDER_STATUS_SEND);
                            gCommodityOrder.setPayDate(new Date());
                            if (gCommodityOrder.getCouponId() != null)
                                igCouponUserService.use(igCouponUserService.selectGCouponUserVoById(gCommodityOrder.getCouponId()));
                            igCommodityOrderService.updateGCommodityOrder(gCommodityOrder);
                        }
                    } else if (SysConsts.PAY_BACK_PRINT == type) {
                        FacPrintOrder facPrintOrder = iFacPrintOrderService.selectFacPrintOrderByNumber(out_trade_no);
                        if (!facPrintOrder.isPay()) {
                            facPrintOrder.setPay(true);
                            facPrintOrder.setPayDate(new Date());
                            facPrintOrder.setTransactionId(transaction_id);
                            if (facPrintOrder.getCouponId() != null)
                                igCouponUserService.use(igCouponUserService.selectGCouponUserVoById(facPrintOrder.getCouponId()));
                            // 调用打印接口
                            System.out.println("执行打印");
                            boolean isPrint = HttpPrintUtils.print(facPrintOrder);
                            facPrintOrder.setPrint(isPrint);
                            iFacPrintOrderService.updateFacPrintOrder(facPrintOrder);
                            // 计算佣金
                            iSysUserBrokerageService.addSysUserBrokerageMoney(facPrintOrder.getFacilityCode(), facPrintOrder.getPayMoney());

                            //调用分账
                            shareOrder(facPrintOrder);

                        } else if (!facPrintOrder.isPrint()) {
                            System.out.println("执行打印");
                            boolean isPrint = HttpPrintUtils.print(facPrintOrder);
                            facPrintOrder.setPrint(isPrint);
                            iFacPrintOrderService.updateFacPrintOrder(facPrintOrder);
                        }
                    } else if (SysConsts.PAY_BACK_PAY == type) {
                        SysUserExpend expend = iSysUserExpendService.selectSysUserExpendById(Long.parseLong(out_trade_no));
                        System.out.println("执行充值" + expend.isPay());
                        if (!expend.isPay()) {
                            SysUser user = iSysUserService.selectUserById(expend.getUserId());
                            iSysUserService.updateUserMoney(user.getUserId(), user.getMoney() + expend.getMoney());
                            System.out.println("用户金额：" + user.getMoney());
                            System.out.println("充值用户：" + user.getUserId() + "金额：" + expend.getMoney());
                        }
                    }

                    xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                } else {
//                        log.info("微信手机支付回调失败订单号:{}", out_trade_no);
                    xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                }
                System.out.println("回调执行成功");
            }
            if (SysConsts.PAY_BACK_PAY == type && out_trade_no != null) {
                iSysUserExpendService.deleteSysUserExpendById(Long.parseLong(out_trade_no));
            }
            return xmlBack;

//            } else {
//                // 签名错误，如果数据里没有sign字段，也认为是签名错误
//                //失败的数据要不要存储？
////                log.error("手机支付回调通知签名错误");
//                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
//
//                return xmlBack;
//            }
        } catch (
                Exception e) {
//            log.error("手机支付回调通知失败", e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }

    @Override
    public WxSharingOrderResp shareOrder(FacPrintOrder facPrintOrder) throws Exception {
        //判断是否需要分账
        //todo
        System.out.println("执行分账");
        WxSharingOrderResp resp =  iWxPayService.oncePaySharing(facPrintOrder);
        //
        if(resp != null && "SUCCESS".equals(resp.getReturn_code())
                && "SUCCESS".equals(resp.getResult_code())){
            System.out.println("调用分账接口成功");
            //更改分账记录状态
            saRecordService.updateOrderState(1, facPrintOrder.getId()+"");

            //发送分账通知
            List<SeparateVo> voList = saRecordService.queryUserRecord(facPrintOrder.getId());
            if (voList != null && voList.size() > 0) {
                voList.forEach(user -> {
                    //组装模板消息内容
                    if (StringUtils.isNotBlank(user.getOpenId())) {
                        MessageTemplateModel templateModel = new MessageTemplateModel();
                        templateModel.setFirst(MessageTemplateModel.Model.init("您有一笔分账即将到账，请注意查收"));
                        templateModel.setKeyword1(MessageTemplateModel.Model.init(String.valueOf(user.getGetMoney())));
                        templateModel.setKeyword2(MessageTemplateModel.Model.init("微信支付"));
                        templateModel.setKeyword3(MessageTemplateModel.Model.init(facPrintOrder.getNumber()));
                        templateModel.setKeyword4(MessageTemplateModel.Model.init(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss")));
                        templateModel.setRemark(MessageTemplateModel.Model.init("感谢你的使用。"));
                        serviceNumberService.sendTemplate(user.getOpenId(), templateModel);
                    }
                });
            }
        }else{
            //调用分账接口失败咋处理？
            //更改分账记录状态
            saRecordService.updateOrderState(3, facPrintOrder.getId()+"");
            String return_msg = resp != null ? resp.getReturn_msg():"";
            String errorRes = resp != null ? resp.getErr_code_des():"";
            String errorCode = resp != null ? resp.getErr_code():"";
            System.out.println("调用分账接口成功,分账失败,orderId="+facPrintOrder.getId()+",orderNo="+facPrintOrder.getNumber()
                    +",return_msg:"+return_msg+",errorCode:"+errorCode+",errorRes:"+errorRes);

        }
        return resp;
    }

    @Override
    public String payBackByCommodity(String resXml) {
        return payBack(resXml, SysConsts.PAY_BACK_COMMODITY);
    }

    @Override
    public String payBackByPrint(String resXml) {
        return payBack(resXml, SysConsts.PAY_BACK_PRINT);
    }

    @Override
    public String payBackByPay(String resXml) {
        return payBack(resXml, SysConsts.PAY_BACK_PAY);
    }

}
